#include "../../../../mac/mac_parse.h"
#include <string.h>

int8 frm_ctrl_cmp(uint16 gen_value, mac_frm_ctrl_t *gen)
{
    mac_frm_ctrl_t parse;

    mac_parse_frm_ctrl(gen_value, &parse);
/*
    MAC_DEBUG("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
             parse.frm_type,
             parse.en_sec,
             parse.frm_pend,
             parse.ack,
             parse.pan_id_comp,
             parse.dest_addr_m,
             parse.frm_ver,
             parse.src_addr_m);
*/

    if (gen->frm_type     ==     parse.frm_type    &&
        gen->en_sec       ==     parse.en_sec      &&
        gen->frm_pend     ==     parse.frm_pend    &&
        gen->ack          ==     parse.ack         &&
        gen->pan_id_comp  ==     parse.pan_id_comp &&
        gen->dest_addr_m  ==     parse.dest_addr_m &&
        gen->frm_ver      ==     parse.frm_ver     &&
        gen->src_addr_m   ==     parse.src_addr_m) {
        return 0;
    } else {
        return -1;
    }
}

int8 mac_hdr_cmp(buf_t *buf, mac_hdr_t *gen_hdr)
{
    mac_hdr_t parse_hdr;
    mac_frm_ctrl_t *gen_ctrl;
    mac_frm_ctrl_t *parse_ctrl;
    addr_t *gen_dest_addr;
    addr_t *gen_src_addr;
    addr_t *parse_dest_addr;
    addr_t *parse_src_addr;
    uint8 r;

    r = mac_parse_hdr(buf, &parse_hdr);

    if (r == -1) {
        return r;
    }

    gen_ctrl = &gen_hdr->ctrl;
    parse_ctrl = &parse_hdr.ctrl;

    gen_dest_addr = &gen_hdr->dest_addr;
    gen_src_addr = &gen_hdr->src_addr;
    parse_dest_addr = &parse_hdr.dest_addr;
    parse_src_addr = &parse_hdr.src_addr;

    /*
    MAC_DEBUG("mac_hdr_cmp 1.\n");
    MAC_DEBUG("gen_hdr->dsn is %d\n", gen_hdr->dsn);
    MAC_DEBUG("gen_hdr->dest_pan_id is %d\n", gen_hdr->dest_pan_id);
    MAC_DEBUG("gen_dest_addr->a.addr64 is %d\n", (int)gen_dest_addr->a.addr64);
    MAC_DEBUG("gen_dest_addr->a.addr16 is %d\n", gen_dest_addr->a.addr16);
    MAC_DEBUG("gen_hdr->src_pan_id is %d\n", gen_hdr->src_pan_id);
    MAC_DEBUG("gen_src_addr->a.addr64 is %d\n", (int)gen_src_addr->a.addr64);
    MAC_DEBUG("gen_src_addr->a.addr16 is %d\n", gen_src_addr->a.addr16);

    MAC_DEBUG("\n");
    MAC_DEBUG("parse_hdr.dsn is %d\n", parse_hdr.dsn);
    MAC_DEBUG("parse_hdr.dest_pan_id is %d\n", parse_hdr.dest_pan_id);
    MAC_DEBUG("parse_dest_addr->a.addr64 is %d\n", (int)parse_dest_addr->a.addr64);
    MAC_DEBUG("parse_dest_addr->a.addr16 is %d\n", parse_dest_addr->a.addr16);
    MAC_DEBUG("parse_hdr.src_pan_id is %d\n", parse_hdr.src_pan_id);
    MAC_DEBUG("parse_src_addr->a.addr64 is %d\n", (int)parse_src_addr->a.addr64);
    MAC_DEBUG("parse_src_addr->a.addr16 is %d\n", parse_src_addr->a.addr16);
    */

    if (gen_hdr->dsn == parse_hdr.dsn &&
        gen_hdr->dest_pan_id == parse_hdr.dest_pan_id &&
        ((gen_ctrl->dest_addr_m == ADDR_64_M)?
        ((gen_dest_addr->a).addr64 == parse_dest_addr->a.addr64) :
        ((gen_dest_addr->a).addr16 == parse_dest_addr->a.addr16)
        ) &&
        ((gen_ctrl->src_addr_m == ADDR_64_M)?
        ((gen_src_addr->a).addr64 == parse_src_addr->a.addr64) :
        ((gen_src_addr->a).addr16 == parse_src_addr->a.addr16)
        ) &&
        ((gen_ctrl->pan_id_comp == 0)?
        (gen_hdr->src_pan_id == parse_hdr.src_pan_id) : (1))) {
        return 0;
    } else {
        return -1;
    }
}

int8 sup_frm_cmp(uint16 gen_value, mac_sup_frm_t *gen)
{
    mac_sup_frm_t parse;

    mac_parse_sup_frm(gen_value, &parse);

    if ((gen->bcn_order       ==     parse.bcn_order   ) &&
        (gen->sup_frm_order   ==     parse.sup_frm_order) &&
        (gen->fnl_cap_slot    ==     parse.fnl_cap_slot) &&
        (gen->ble             ==     parse.ble         ) &&
        (gen->pan_coord       ==     parse.pan_coord   ) &&
        (gen->assoc_pmit      ==     parse.assoc_pmit  )) {

        return 0;
    } else {
        return -1;
    }
}

int8 cap_info_cmp(uint8 gen_value, mac_cap_info_t *gen)
{
    mac_cap_info_t parse;

    mac_parse_cap_info(gen_value, &parse);

    if (parse.altnt_pan_coord   ==   gen->altnt_pan_coord   &&
        parse.dev_type          ==   gen->dev_type          &&
        parse.pw_src            ==   gen->pw_src            &&
        parse.rec_on_when_idle  ==   gen->rec_on_when_idle  &&
        parse.sec_cap           ==   gen->sec_cap           &&
        parse.alloc_addr        ==   gen->alloc_addr) {

        return 0;
    } else {
        return -1;
    }
}

int8 ack_cmp(mac_frm_ack_t *gen)
{
    mac_frm_ack_t parse;
    buf_t buf;
    mac_hdr_t hdr;
    int8 len = 0;

    buf.ptr = &buf.array[127];
    buf.length = 0;

    mac_gen_ack(&buf, gen);

    mac_parse_hdr(&buf, &hdr);
    /*
    MAC_DEBUG("frm_type is %d\n", hdr.ctrl.frm_type);
    MAC_DEBUG("en_sec is %d\n", hdr.ctrl.en_sec);
    MAC_DEBUG("frm_pend is %d\n", hdr.ctrl.frm_pend);
    MAC_DEBUG("ack is %d\n", hdr.ctrl.ack);
    MAC_DEBUG("pan_id_comp is %d\n", hdr.ctrl.pan_id_comp);
    MAC_DEBUG("dest_addr_m is %d\n", hdr.ctrl.dest_addr_m);
    MAC_DEBUG("frm_ver is %d\n", hdr.ctrl.frm_ver);
    MAC_DEBUG("src_addr_m is %d\n", hdr.ctrl.src_addr_m);
    */

    parse.dsn = hdr.dsn;
    parse.pend = hdr.ctrl.frm_pend;
    /*
    MAC_DEBUG("ack_cmp: pend is %d, dsn is %d\n", parse.pend, parse.dsn);
    */

    if (gen->dsn == parse.dsn &&
        gen->pend == parse.pend) {
        return 0;
    } else {
        return -1;
    }
}

int8 assoc_req_cmp(mac_frm_assoc_req_t *req)
{
    buf_t buf;
    mac_hdr_t hdr;
    mac_frm_assoc_req_t parse;

    memset(&buf.array[0], 0, sizeof(buf.array));
    buf.ptr = &buf.array[127];
    buf.length = 0;

    mac_gen_assoc_req(&buf, req); 
    mac_parse_hdr(&buf, &hdr);
    mac_parse_cmd(&buf);
    mac_parse_assoc_req(&buf, &parse);

    parse.src.mode = hdr.src_addr.mode;
    parse.src.a.addr64 = hdr.src_addr.a.addr64;
    parse.dest.mode = hdr.dest_addr.mode;
    parse.dest.a.addr64 = hdr.dest_addr.a.addr64;
    parse.src_pan_id = hdr.src_pan_id;
    parse.dest_pan_id = hdr.dest_pan_id;
    parse.dsn = hdr.dsn;
    
    /*
    MAC_DEBUG("assoc_req_cmp: req->src.mode is 0x%x\n", req->src.mode);
    MAC_DEBUG("assoc_req_cmp: parse.src.mode is 0x%x\n", parse.src.mode);
    MAC_DEBUG("assoc_req_cmp: req->src.a.addr64 is 0x%x\n", (uint32)req->src.a.addr64);
    MAC_DEBUG("assoc_req_cmp: parse.src.a.addr64 is 0x%x\n", (uint32)parse.src.a.addr64);
    MAC_DEBUG("assoc_req_cmp: req->cap_info is 0x%x\n", req->cap_info);
    MAC_DEBUG("assoc_req_cmp: parse.cap_info is 0x%x\n", parse.cap_info);
    */
    
    if (req->src.mode == parse.src.mode &&
        req->src.a.addr64 == parse.src.a.addr64 &&
        req->dest.mode == parse.dest.mode &&
        req->dest.a.addr64 == parse.dest.a.addr64 &&
        req->src_pan_id == parse.src_pan_id &&
        req->dest_pan_id == parse.dest_pan_id &&
        req->cap_info == parse.cap_info &&
        req->dsn == parse.dsn) {
        return 0;
    } else {
        return -1;
    }
}

int8 assoc_resp_cmp(mac_frm_assoc_resp_t *resp)
{
    buf_t buf;
    mac_hdr_t hdr;
    mac_frm_assoc_resp_t parse;
    uint8 cmd_id;

    memset(&buf.array[0], 0, sizeof(buf.array));
    buf.ptr = &buf.array[127];
    buf.length = 0;

    mac_gen_assoc_resp(&buf, resp); 
    mac_parse_hdr(&buf, &hdr);
    cmd_id = mac_parse_cmd(&buf);
    /*
    MAC_DEBUG("assoc_resp_cmp: cmd_id is %d\n", cmd_id);
    */
    mac_parse_assoc_resp(&buf, &parse);

    parse.src.mode = hdr.src_addr.mode;
    parse.src.a.addr64 = hdr.src_addr.a.addr64;
    parse.dest.mode = hdr.dest_addr.mode;
    parse.dest.a.addr64 = hdr.dest_addr.a.addr64;
    parse.dsn = hdr.dsn;
    parse.pan_id = hdr.dest_pan_id;

    /*
    MAC_DEBUG("assoc_resp_cmp: parse.src.mode is %d\n", parse.src.mode);
    MAC_DEBUG("assoc_resp_cmp: parse.src.a.addr64 is 0x%x\n", (uint32)parse.src.a.addr64);
    MAC_DEBUG("assoc_resp_cmp: parse.dest.mode is %d\n", parse.dest.mode);
    MAC_DEBUG("assoc_resp_cmp: parse.dest.a.addr64 is 0x%x\n", (uint32)parse.dest.a.addr64);
    MAC_DEBUG("assoc_resp_cmp: short_addr is 0x%x\n", parse.short_addr);
    MAC_DEBUG("assoc_resp_cmp: parse.status is %d\n", parse.status);
    MAC_DEBUG("assoc_resp_cmp: parse.dsn is %d\n", parse.dsn);
    MAC_DEBUG("assoc_resp_cmp: parse.pan_id is 0x%x\n", parse.pan_id);

    MAC_DEBUG("\nassoc_resp_cmp: resp->src.mode is %d\n", resp->src.mode);
    MAC_DEBUG("assoc_resp_cmp: resp->src.a.addr64 is 0x%x\n", (uint32)resp->src.a.addr64);
    MAC_DEBUG("assoc_resp_cmp: resp->dest.mode is %d\n", resp->dest.mode);
    MAC_DEBUG("assoc_resp_cmp: resp->dest.a.addr64 is 0x%x\n", (uint32)resp->dest.a.addr64);
    MAC_DEBUG("assoc_resp_cmp: short_addr is 0x%x\n", resp->short_addr);
    MAC_DEBUG("assoc_resp_cmp: resp->status is %d\n", resp->status);
    MAC_DEBUG("assoc_resp_cmp: resp->dsn is %d\n", resp->dsn);
    MAC_DEBUG("assoc_resp_cmp: resp->pan_id is 0x%x\n", resp->pan_id);
    */

    if (resp->src.mode == parse.src.mode &&
        resp->src.a.addr64 == parse.src.a.addr64 &&
        resp->dest.mode == parse.dest.mode &&
        resp->dest.a.addr64 == parse.dest.a.addr64 &&
        resp->short_addr == parse.short_addr &&
        resp->status == parse.status &&
        resp->dsn == parse.dsn &&
        resp->pan_id == parse.pan_id) {
        return 0;
    } else {
        return -1;
    }
}

int8 data_req_cmp(mac_frm_data_req_t *req)
{
    buf_t buf;
    mac_hdr_t hdr;
    uint8 cmd_id;

    memset(&buf.array[0], 0, sizeof(buf.array));
    buf.ptr = &buf.array[127];
    buf.length = 0;

    mac_gen_data_req(&buf, req);
    mac_parse_hdr(&buf, &hdr);
    cmd_id = mac_parse_cmd(&buf);

    if (cmd_id == CMD_DATA_REQ) {
        return 0;
    } else {
        return -1;
    }
}

int8 bcn_req_cmp(uint8 bsn)
{
    buf_t buf;
    mac_hdr_t hdr;
    uint8 cmd_id;

    memset(&buf.array[0], 0, sizeof(buf.array));
    buf.ptr = &buf.array[127];
    buf.length = 0;

    mac_gen_bcn_req(&buf, bsn);
    mac_parse_hdr(&buf, &hdr);
    cmd_id = mac_parse_cmd(&buf);

    if (cmd_id == CMD_BCN_REQ) {
        return 0;
    } else {
        return -1;
    }
}


